var jEnv = null;

function onBarClick(e)
{
	alert(e.target.className);
}

// helper function to list methods of an obj to achieve introspection
function listProp(obj)
{
	var propList = "| ";
	for(var name in obj)
	{
		if(typeof(obj[name]) != "undefined")
			propList += (name + "(" + typeof(obj[name]) + "):" + obj[name] + " <br>");
	}
	
	return propList;
}

function listProperties(obj)
{
    var newLine = "<br />";
    var names = Object.getOwnPropertyNames(obj);
    var txt = "";
    txt += (typeof(obj) + newLine);
    for (var i = 0; i < names.length; i++) 
    {
        var prop = names[i];
        txt += (prop + newLine);
 
        // 列出对象的属性配置（descriptor）动用getOwnPropertyDescriptor函数。
        var descriptor = Object.getOwnPropertyDescriptor(obj, prop);
        for (var attr in descriptor) 
        {
            txt += ("..." + attr + ': ' + descriptor[attr] + newLine);
        }
        txt += newLine;
    }

    return txt;
}

function output(txt)
{
	var infoBar = document.getElementById("infobar");
	infoBar.innerHTML = txt;
}

function PreSibling(node)
{
	var e = node.previousSibling;
	while(e != null && e.nodeType != 1)
	{
		e = e.previousSibling;
	}
	return e;
}

function NextSibling(node)
{
	var e = node.nextSibling;
	while(e != null && e.nodeType != 1)
	{
		e = e.nextSibling;
	}
	return e;
}

// get the absolute position in the <body> area
function GetBodyPos(tag)
{
	var pos = new Object();
	pos.left = pos.right = pos.top = pos.bottom = 0;

	var w = tag.offsetWidth;
	var h = tag.offsetHeight;

	var itr = tag;
	while(itr != document.body)
	{
		pos.left += itr.offsetLeft;
		pos.top  += itr.offsetTop;
		itr = itr.offsetParent;
	}

	pos.right = pos.left + w;
	pos.bottom= pos.top  + h;
	return pos;
}

function InsertBlock(beforeDiv)
{
	var content_wrap = document.getElementById(jEnv.contentWrapTag);

	var block = document.createElement("div");

	// apply properties and sub divs
	block.id = jEnv.tempBlockID;
	block.className = jEnv.blockTag;	// "block"

	// droppable
	var droppable = document.createElement("div");
	droppable.className = jEnv.dropTag; //"droppable"

	block.appendChild(droppable);

	// container
	{
		var container = document.createElement("div");
		container.className = jEnv.containerTag + " solidlined";

		var l = document.createElement("div");
		l.className = jEnv.collapseTag;
		l.title = "Click to expand this note";
		container.appendChild(l);

		var c = document.createElement("div");
		c.className = jEnv.contentTag;
		c.tabIndex = 0;
		container.appendChild(c);

		var cinline = document.createElement("div");
		cinline.className = jEnv.inlineTag;
		container.appendChild(cinline);

		var r = document.createElement("div");
		r.className = "r " + jEnv.dragTag;
		container.appendChild(r);
	}// end container

	block.appendChild(container);

	content_wrap.insertBefore(block, beforeDiv);

	InitBlock(block);

	DragInst.RefreshDroppableTable();

	return block;
}

function InitBlock(blockDiv)
{
	// droppable
	var droppable = blockDiv.getElementsByClassName(jEnv.dropTag);
	droppable[0].addEventListener("click", onClickDroppable, true);

	// apply selection inst
	var containerList = blockDiv.getElementsByClassName(jEnv.containerTag);
	if(containerList.length == 0) return; // the last block doesn't have a container div

	var containerDiv = containerList[0];
	containerDiv.addEventListener("mousedown", onSelectDraggable, true);

	// draggable
	var draggables = containerDiv.getElementsByClassName(jEnv.dragTag);
	draggables[0].addEventListener("mousedown", DragInst.Start, true);

	// assign a new property, to store the collapse state
	containerDiv.collapse = 0;	// always fold
	var collapse = containerDiv.getElementsByClassName(jEnv.collapseTag);
	collapse[0].addEventListener("mousedown", onCollapseBtnClick, true);
	collapse[0].addEventListener("mouseover", onCollapseBtnHover, true);
	collapse[0].addEventListener("mouseout", onCollapseBtnOut, true);

	var contentbody = containerDiv.getElementsByClassName(jEnv.contentTag);
	contentbody[0].style.display = "none";
	contentbody[0].contentEditable = "true";
	contentbody[0].addEventListener("blur", onBodyBlur, true);

	var inlinebody = containerDiv.getElementsByClassName(jEnv.inlineTag);
	inlinebody[0].style.display = "block";
	inlinebody[0].innerHTML = contentbody[0].innerText;
}

function InitElements()
{
	var blocks = document.getElementsByClassName(jEnv.blockTag);
	
	for( var i = 0; i < blocks.length; i++)
	{
		InitBlock(blocks[i]);
	}

	DragInst.RefreshDroppableTable();
}

// state, -1: swap container state, 0: collapse, 1: expand
function CollapseBlock(container, state)
{
	var content = container.getElementsByClassName(jEnv.contentTag);
	var inline  = container.getElementsByClassName(jEnv.inlineTag);
	var collapse= container.getElementsByClassName(jEnv.collapseTag);

	content = content[0];
	inline  = inline[0];
	collapse= collapse[0];

	if(state == -1) 
		state = 1 - container.collapse;

	if(state == 1 )
	{
		container.collapse = 1;
		collapse.style.backgroundPosition = "-12px 0px";
		
		inline.style.display = "none";
		content.style.display= "block";
	}
	else
	{
		container.collapse = 0;
		collapse.style.backgroundPosition = "-36px 0px";

		inline.style.display = "block";
		content.style.display= "none";
		inline.innerHTML = content.innerText;
	}
}

function onCollapseBtnClick(e)
{
	var container = e.target.parentNode;

	CollapseBlock(container, -1);

	DragInst.RefreshDroppableTable();

	e.stopPropagation();
	e.preventDefault();
}

function onCollapseBtnHover(e)
{
	var content = e.target.parentNode;

	if(content.collapse == 0)
	{
		e.target.style.backgroundPosition = "-36px 0px";
	}
	else
	{
		e.target.style.backgroundPosition = "-12px 0px";
	}
}

function onCollapseBtnOut(e)
{
	var content = e.target.parentNode;
	if(content.collapse == 0)
	{
		e.target.style.backgroundPosition = "-24px 0px";
	}
	else
	{
		e.target.style.backgroundPosition = "-00px 0px";
	}
}

function onClickDroppable(e)
{

	var block = InsertBlock(e.target.parentNode);

	// focus on the new block
	var container = block.getElementsByClassName(jEnv.containerTag);
	CollapseBlock(container[0], 1);

	var content = block.getElementsByClassName(jEnv.contentTag);
	content[0].focus();
}	

function onBodyBlur(e)
{
	if(e.target.innerText.length == 1 && e.target.innerText.charCodeAt(0))
		e.target.innerText = "";
	if(e.target.innerText != "") return;

	var block = e.target.parentNode.parentNode;

	// delete null block
	if(block != null && block.id != jEnv.tempBlockID)
	{
		// delete the existing block in the database
		alert("will delete the current block permanently!");
	}

	var contentWrap = document.getElementById(jEnv.contentWrapTag);
	contentWrap.removeChild(block);

	DragInst.RefreshDroppableTable();
}

function onPageLoad()
{
	jEnv = new Object();
	jEnv.pageTag = "page";
	jEnv.contentWrapTag = "content_wrap";
	jEnv.blockTag = "block";
	jEnv.containerTag = "container";
	jEnv.dropTag = "droppable";
	jEnv.collapseTag  = "l";
	jEnv.contentTag = "c";
	jEnv.inlineTag = "c_inline";
	jEnv.dragTag = "draggable";
	jEnv.tempBlockID = "temp";

	SelectionInst = new Selection();
	initDragHandler();

	InitToolbar();
	InitElements();

	// global key down press to handle shortcut

}

